home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / wvnsrc75.zip / WVFILE.C < prev    next >
Text File  |  1993-02-08  |  10KB  |  366 lines

  1. /*-- WVFILE.C -- File containing routines to do I/O under Windows.
  2.  */
  3.  
  4. #include "windows.h"
  5. #include "wvglob.h"
  6. #include "winvn.h"
  7. #ifndef MAC
  8. #include "winundoc.h"
  9. #include <io.h>
  10. #else
  11. #include <unix.h>
  12. #include <fcntl.h>
  13. #endif
  14.  
  15. #ifdef MAC
  16. extern long int _lread (HANDLE hFile, char *buf, long int bufsize);
  17. extern _llseek (HANDLE hFile, long int offset, int posmode);
  18. #endif
  19.  
  20.  
  21. /*--- function MRROpenFile --------------------------------------------
  22.  *
  23.  *  Perform the same function as Windows' OpenFile, but also
  24.  *  create an instance of a structure that keeps track of file-related
  25.  *  information (most importantly, an file buffer so I don't have to
  26.  *  do 1-byte system reads).
  27.  *
  28.  *    Entry    FileName    is the file name of the file to open.
  29.  *             vRef        is the reference number (MAC only)
  30.  *             Mode        is the mode under which to open the file.
  31.  *
  32.  *    Exit     MRRFile     points to a dynamically-allocated structure
  33.  *                         containing info about the file.
  34.  *             Returns a handle to the file; 0 if failure.
  35.  */
  36. HANDLE
  37. MRROpenFile (FileName, vRef, Mode, MRRFile)
  38.      char *FileName;
  39.      int vRef;
  40.      int Mode;
  41.      TypMRRFile **MRRFile;
  42. {
  43.   HANDLE hMyFile, hMRR;
  44.   TypMRRFile *MyMRRFile;
  45.   int retcode;
  46. #ifdef MAC
  47.   int MacMode;
  48.   int myvRef;
  49.   Str255 pFileName;
  50.   int fRefNum;
  51.   OSErr myErr;
  52. #endif
  53.  
  54.   hMRR = LocalAlloc (LMEM_FIXED, sizeof (TypMRRFile));
  55.   if (!hMRR)
  56.     {
  57.       return (0);
  58.     }
  59.   else
  60.     {
  61.       MyMRRFile = (TypMRRFile *) LocalLock (hMRR);
  62.       MyMRRFile->hthis = hMRR;
  63.       MyMRRFile->bufidx = 0;
  64.       MyMRRFile->bytesread = 0;
  65.       MyMRRFile->eofflag = FALSE;
  66.       MyMRRFile->mode = Mode;
  67.  
  68.       if (Mode == OF_WRITE)
  69.     {
  70.       hMyFile = OpenFile (FileName, &(MyMRRFile->of), OF_EXIST);
  71.       if (hMyFile == -1)
  72.         Mode = OF_CREATE;
  73.     }
  74.       hMyFile = retcode = OpenFile ((char far *) FileName, &(MyMRRFile->of), Mode);
  75.       if (retcode == (-1))
  76.     {
  77.       LocalUnlock (hMRR);
  78.       LocalFree (hMRR);
  79.       return (0);
  80.     }
  81.       else
  82.     {
  83.       MyMRRFile->hFile = hMyFile;
  84.     }
  85.     }
  86.   *MRRFile = MyMRRFile;
  87.   return ((HANDLE) hMyFile);
  88. }
  89.  
  90. /*--- function MRRCloseFile --------------------------------------------
  91.  *
  92.  *  Perform the same function as the close function, but also
  93.  *  deallocate the structure allocated by MRROpenFile.
  94.  *
  95.  *    Entry    MRRFile  points to a structure describing the file.
  96.  */
  97. void
  98. MRRCloseFile (MRRFile)
  99.      TypMRRFile *MRRFile;
  100. {
  101.   HANDLE hMyMRRFile;
  102.   long int nbytes;
  103.   int num_written = 0;
  104.  
  105.   if (MRRFile->mode == OF_WRITE || MRRFile->mode == OF_CREATE)
  106.     {
  107. // write is not in win32.  What was this doing???
  108. //        write (MRRFile->hFile, MRRFile->buf, MRRFile->bufidx);
  109.       WriteFile (MRRFile->hFile, MRRFile->buf, MRRFile->bufidx, &num_written, NULL);
  110.       if (num_written != MRRFile->bufidx)
  111.         MessageBox (hWndConf, "error in MRRWriteLine, num_written != MRRFile->bufidx", "WinVN", MB_OK && MB_ICONHAND);
  112.     }
  113. #ifdef MAC
  114.   FSClose ((int) MRRFile->hFile);
  115.   FlushVol (NULL, MRRFile->vRef);
  116. #else
  117. //  _lclose (MRRFile->hFile);
  118. // Let's try the win32 function:
  119.   CloseHandle (MRRFile->hFile);
  120. #endif
  121.   hMyMRRFile = MRRFile->hthis;
  122.   LocalUnlock (hMyMRRFile);
  123.   LocalFree (hMyMRRFile);
  124. }
  125.  
  126. /*--- function MRRReadLine ---------------------------------------------
  127.  *
  128.  *  Read in a line from a file, very much like "fgets".
  129.  *  Lines are assumed to be terminated by CR/LF (except that this
  130.  *  is optional for the last line in a file).
  131.  *
  132.  *  No CR, LF, or zero byte is placed in the user's buffer or
  133.  *  counted as a data byte in the returned count.
  134.  *
  135.  *    Entry    MRRFile  points to a structure describing the file.
  136.  *             Linebuf  is the place to put the line.
  137.  *             Len      is the length of Linebuf.
  138.  *
  139.  *    Exit     Linebuf  contains a line.
  140.  *             Returns number of characters read.  0 means an empty line;
  141.  *              -1 means EOF.
  142.  */
  143. int
  144. MRRReadLine (MRRFile, Linebuf, Len)
  145.      TypMRRFile *MRRFile;
  146.      char *Linebuf;
  147.      int Len;
  148. {
  149.   int BytesReturned = 0;
  150.   char ch;
  151.  
  152.   /* If we hit the EOF while reading last time, we might not have   */
  153.   /* had to return an EOF indication then--but we certainly do now. */
  154.  
  155.   if (MRRFile->eofflag)
  156.     return (-1);
  157.  
  158.   /* Read bytes until we exhaust the user's buffer,                 */
  159.   /* empty our own internal buffer,                                 */
  160.   /* or hit a CR (which hopefully belongs to a CR/LF pair).         */
  161.  
  162. readlp:;
  163.   while (Len && MRRFile->bufidx < MRRFile->bytesread &&
  164.      (ch = MRRFile->buf[MRRFile->bufidx]) != '\r' && ch != '\n')
  165.     {
  166.       *(Linebuf++) = ch;
  167.       BytesReturned++;
  168.       (MRRFile->bufidx)++;
  169.       Len--;
  170.     }
  171.  
  172.   /* If we emptied our own internal buffer, fill 'er up again       */
  173.   /* from the file.  If the read hits EOF, return the user's        */
  174.   /* data now (indicating EOF if we never got any data bytes        */
  175.   /* else go back up and continue taking from the buffer.           */
  176.  
  177.   if (MRRFile->bufidx >= MRRFile->bytesread)
  178.     {
  179.       MRRFile->bufidx = 0;
  180.       MRRFile->bytesread = _lread (MRRFile->hFile, MRRFile->buf, BUFSIZE);
  181.       if (MRRFile->bytesread > 0)
  182.     {
  183.       goto readlp;
  184.     }
  185.       else
  186.     {
  187.       MRRFile->eofflag = TRUE;
  188.       if (!BytesReturned)
  189.         BytesReturned--;
  190.       goto endit;
  191.     }
  192.     }
  193.  
  194.   /* If we reach here, we either filled the user's buffer or        */
  195.   /* hit a CR.  No EOF was encountered.                             */
  196.   /* Either way, we must now skip to the beginning of the next      */
  197.   /* line.  This means skipping to the next LF.  Since in most      */
  198.   /* cases the user does specify a big enough buffer, in most       */
  199.   /* cases all we are doing here is reading up the next character   */
  200.   /* (assuming it's a LF).                                          */
  201.   /* All data that should go in the user's buffer is there by now.  */
  202.  
  203. skipLF:;
  204. #ifndef MAC
  205.   while (MRRFile->bufidx < MRRFile->bytesread &&
  206.      MRRFile->buf[MRRFile->bufidx] != '\n')
  207.     {
  208.       (MRRFile->bufidx)++;
  209.     }
  210. #endif
  211.   /* We either found the LineFeed we were looking for, or hit       */
  212.   /* the end of our internal buffer.  If the latter, fill 'er       */
  213.   /* up and try again.                                              */
  214.  
  215.   if (MRRFile->bufidx >= MRRFile->bytesread)
  216.     {
  217.       MRRFile->bufidx = 0;
  218.       MRRFile->bytesread = _lread (MRRFile->hFile, MRRFile->buf, BUFSIZE);
  219.       if (MRRFile->bytesread > 0)
  220.     {
  221.       goto skipLF;
  222.     }
  223.       else
  224.     {
  225.       MRRFile->eofflag = TRUE;
  226.       goto endit;
  227.     }
  228.     }
  229.  
  230.   /* The buffer pointer is now pointing at the LF.  Advance         */
  231.   /* it by one so we'll get the first character of the next         */
  232.   /* line next time.                                                */
  233.   /* If this takes us past the end of the buffer, no problem.       */
  234.  
  235. #ifndef MAC
  236.   if (MRRFile->buf[MRRFile->bufidx] == '\n')
  237.     (MRRFile->bufidx)++;
  238. #else
  239.   if (MRRFile->buf[MRRFile->bufidx] == '\r')
  240.     (MRRFile->bufidx)++;
  241. #endif
  242.  
  243. endit:;
  244.   return (BytesReturned);
  245. }
  246.  
  247. /*--- function MRRWriteLine ---------------------------------------------
  248.  *
  249.  *  Write out a line of text, followed by a CR and LF.
  250.  *
  251.  *    Entry    MRRFile  points to a structure describing the file.
  252.  *             LineBuf  points to line buffer to write out.
  253.  *             Len      is the number of bytes to write.
  254.  */
  255. BOOL
  256. MRRWriteLine (MRRFile, LineBuf, Len)
  257.      TypMRRFile *MRRFile;
  258.      char far *LineBuf;
  259.      int Len;
  260. {
  261.   int BytesToCopy;
  262.   static NotFirst = 0;
  263.   long int nbytes;
  264.   int num_written = 0;
  265.  
  266.   do
  267.     {
  268.       BytesToCopy = Len < (BUFSIZE - MRRFile->bufidx) ?
  269.     Len : BUFSIZE - MRRFile->bufidx;
  270.       MoveBytes (LineBuf, (char far *) (MRRFile->buf + MRRFile->bufidx), BytesToCopy);
  271.       MRRFile->bufidx += BytesToCopy;
  272.       LineBuf += BytesToCopy;
  273.       Len -= BytesToCopy;
  274.       if (MRRFile->bufidx >= BUFSIZE)
  275.     {
  276. // write is not in win32.  What was this doing???
  277. //      write (MRRFile->hFile, MRRFile->buf, BUFSIZE);
  278.       WriteFile (MRRFile->hFile, MRRFile->buf, BUFSIZE, &num_written, NULL);
  279.       if (num_written != BUFSIZE)
  280.         MessageBox (hWndConf, "error in MRRWriteLine, num_written != BUFSIZE", "WinVN", MB_OK && MB_ICONHAND);
  281.       MRRFile->bufidx = 0;
  282.     }
  283.     }
  284.   while (Len > 0);
  285.  
  286.   if (!(NotFirst++))
  287.     {
  288. #ifndef MAC
  289.       MRRWriteLine (MRRFile, "\r\n", 2);
  290. #else
  291.       MRRWriteLine (MRRFile, "\r\n", 1);
  292. #endif
  293.     }
  294.   NotFirst--;
  295.   return (1);
  296. }
  297.  
  298. /*-- function MRRWriteDocument -----------------------------------------
  299.  *
  300.  *  Write out an entire document to disk.
  301.  *
  302.  *  Entry   Document    points to a document.
  303.  *          Offset      is the number of bytes to skip at the beginning
  304.  *                      of the line (between the end of the structure
  305.  *                      described in TypLine and the beginning of text).
  306.  *                      In most cases this will be zero.
  307.  *          szFileName  points to the file name to save to.
  308.  *          vRef        points to the directory--used only by Macintosh.
  309.  *          Append      is TRUE iff we should append to the file.
  310.  *
  311.  *    Returns TRUE iff we wrote the file OK.
  312.  */
  313. BOOL
  314. MRRWriteDocument (Document, Offset, szFileName, vRef, Append)
  315.      TypDoc *Document;
  316.      int Offset;
  317.      char *szFileName;
  318.      int vRef;
  319.      BOOL Append;
  320. {
  321.   TypMRRFile *MRRFile;
  322.   HANDLE hFile;
  323.   HANDLE hBlock;
  324.   TypBlock far *BlockPtr;
  325.   TypLine far *LinePtr;
  326.   int mode;
  327.  
  328.   if (Append)
  329.     {
  330.       mode = OF_WRITE;
  331.     }
  332.   else
  333.     {
  334.       mode = OF_CREATE;
  335.     }
  336.   hFile = MRROpenFile (szFileName, vRef, mode, &MRRFile);
  337.   if (Append)
  338.     {
  339.       _llseek (hFile, 0L, 2);
  340.     }
  341.  
  342.   if (hFile)
  343.     {
  344.       LockLine (Document->hFirstBlock, sizeof (TypBlock), (TypLineID) 0L, &BlockPtr, &LinePtr);
  345.       while (LinePtr->length != END_OF_BLOCK)
  346.     {
  347.       MRRWriteLine (MRRFile, ((char far *) LinePtr) + Offset + sizeof (TypLine),
  348. #if 1
  349.           lstrlen (((char far *) LinePtr) + sizeof (TypLine) + Offset));
  350. #else
  351.              LinePtr->length - sizeof (TypLine) - sizeof (int) - 1);
  352. #endif
  353.       NextLine (&BlockPtr, &LinePtr);
  354.     }
  355.       GlobalUnlock (BlockPtr->hCurBlock);
  356.       MRRCloseFile (MRRFile);
  357.     }
  358.   else
  359.     {
  360.       return (0);
  361.     }
  362.   return (TRUE);
  363. }
  364.  
  365. 
  366.